package my.algorithms.mcorrea.topcoder;

import java.util.HashSet;
import java.util.Set;

/**
 *
 * @author mcorrea
 */
public class NetworkXOneTimePad {

	public static void main(String[] args) {
		//System.out.println(crack(new String[]{"110", "001"}, new String[]{"101", "010"}));
	//	System.out.println("------------------------------");
		//System.out.println(crack(new String[]{"00", "01", "10", "11"},
		//		new String[]{"00", "01", "10", "11"}));
		
		System.out.println("------------------------------");
		System.out.println(crack(new String[]{"01", "10"}, new String[]{"00"}));
		
	//	System.out.println("------------------------------");
	//	System.out.println(crack(new String[]{"000", "111", "010", "101", "110", "001"},
		//		new String[]{"011", "100"}));


		System.out.println(crack(new String[]{"00111110100110110001010110010100110000011", "11010100010010001001111110100001100011111", "11101111101111000011011110001101111101001", "01010110100001100010000001011010011111110", "11111001100110011100101100101000111000010", "11011001111100010100101011010000001011100", "01101101100000101101010001001111111111001", "11111100001101100100001111111000101110010", "00101011000101011101111110001110110101111", "10101001010000101111110001000110010110011", "01011111010101110011111111110111101111111", "10110001110111010011011111110110010110010", "11100001001111010101011111100101010010110", "10011100001110000110111101011011111101100", "11101010010011001011000011111001100100110", "00001101001010011100110100100010011001101", "01101111001101111100100001001011110111111", "11000111010110111010011100001001010100010", "11001111110010000000101100010010001101010", "01000111101110101110100101100010010011110", "00100110111111100111000010010100100001111", "01011110101101010010110101110001101111111", "01010010011100011110100100110111111100100", "11111000111110101111001100011001100110010", "00110110100001011011101011111100100001001", "11011101111011001010110011011011111011010", "01100011101001011011100001001010110000000", "00101010111000100101100111010110000111011", "10001111110110001010111001111101101100101", "01111011000011111000001001001110110111101", "00011101110010011010000000001001110010101", "00000100100001001101010111000100001001101", "00111000100111110111110111111011110000111", "01010101000100000100101011011101001011010", "00011101000001110100010110101110011011101", "01100000111111001111001110101000111111001", "00001100111110010010000011001010111001101", "10111000001000000100000000010110101100010", "10011101100111000000110010111111011000001", "01101100101110101000011011110111001011010", "01111100011110000001000000010000111110100", "00101001011100000111111010110100101001101", "10100000000000111101000101110110110100001", "01000011001011101101000111010001101101011", "11101111001001111001111000100101110001000", "00111110001010011100111011111010110100011"},
				new String[]{"10101110010101111101000110000000011100111", "10110000001101101101110011101111001101111", "01011100111000010011111010110101011110111", "00100001111010110101110101010010101011011", "01100111000101011001011010011001000000001", "00010100100100011100111001001111000000100", "01001111111100100000011000011101101001010", "10000100010100001000000111011110000100101", "10100001110110011101111110100000010100101", "11101000010101010101001010111100000010001", "01100010111001010001000111101101011001110", "00000111011100010000111101101001010001101", "11001011100001110111000011000101010000011", "11011101101110011110101111001001110110010", "01010101010001010000110111001111000110010", "11001111000100110100100001110110101110110", "01101001100101001111011011110001101111110", "10111110001011000001101111101000011100001", "11100100000100110010011111100011110110010", "11110100110100011011000100000100000011100", "10100010010010111111100011000010111010011", "00110000100010011110000100000010010001010", "00010101001101011010110110101011100101001", "00111001011101001001011011100010101011010", "10100011101111000111111010011010001000111", "11101011000011000001100101011110001101000", "01100111100011100011111100110001001100000", "01000111011000011010101000000110110000010", "11110011101001100010001101011010001010101", "11010111111111101001111011100011010010111", "11011010110110000100100000100011000001100", "01010001010110001110101111000100110110100", "01110001001100000110101000111100000101010", "10000101100000000110110000110110100100101"}));


	}

	public static int crack(String[] plaintexts, String[] ciphertexts) {

		long[] ptextnumber = new long[plaintexts.length];
		long[] ctextnumber = new long[ciphertexts.length];
		
		for(int i=0;i<plaintexts.length; i++){
			ptextnumber[i] = Long.parseLong(plaintexts[i], 2);//base 2 to base 10
		}
		
		for(int i=0;i<ctextnumber.length; i++){
			ctextnumber[i] = Long.parseLong(ciphertexts[i], 2);//base 2 to base 10
		}
		
		
		Set<String> keys = new HashSet<String>();
		for(int i=0;i<ptextnumber.length;i++){
			
			Set<String> setkeys = new HashSet<String>();
			for(int j=0; j<ctextnumber.length; j++){
				String key =  Long.toBinaryString( (ptextnumber[i]^ctextnumber[j]))  ;
				setkeys.add(key);
			}
			
				keys.addAll(setkeys);
			
		}
		
		for(String x: keys){
			System.out.println(x);
		}
		
		return keys.size();
		
		/*Set<String> keys = new HashSet<String>();
		String ptext = plaintexts[0];
		for (String ctext : ciphertexts) {
			if (keys.isEmpty()) {//first round find optional keys
				StringBuilder key = new StringBuilder();
				for (int k = 0; k < ptext.length(); k++) {
					int n1 = ptext.charAt(k) == '0' ? 0 : 1;
					int n2 = ctext.charAt(k) == '0' ? 0 : 1;
					int keyBit = ((n1 ^ 0) == n2) ? 0 : 1;
					key.append("").append(keyBit);
				}
				//System.out.println(key.toString());
				keys.add(key.toString());
			}
		}
		
		for(int i=0; i<plaintexts.length; i++){
			
			for(String key: keys){
				boolean yes = false;
				StringBuilder cipher = new StringBuilder();
				for (int k = 0; k < ptext.length(); k++) {
					
					int n1 = plaintexts[i].charAt(k) == '0' ? 0 : 1;
					int n2 = key.charAt(k) == '0' ? 0 : 1;
					cipher.append("").append((n1^n2));
				}
				
				for(String ctext: ciphertexts){
					if(ctext.equals(cipher.toString())){
						yes = true;
						break;
					}
				}
				if(!yes){
					keys.remove(key);
				}
				
			}
		}
		
		
	
	return keys.size();*/
}
}
